<template>
  <div :id="'editor' + index" />
</template>

<script lang="ts" setup>
import { nextTick, onMounted, watch } from "vue";
import { java } from "@codemirror/lang-java";
import { oneDark } from "@codemirror/theme-one-dark";
import {
  EditorState,
  Extension,
  Compartment,
  StateEffect
} from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import { basicSetup } from "codemirror";
const props = defineProps({
  value: {
    type: String,
    default: ""
  },
  index: {
    type: Number,
    default: 0
  }
});

/**
 * 创建一个compartment,并和对其修改的run函数
 * @param view
 * @returns
 */
// https://codemirror.net/examples/config/
// https://github.com/uiwjs/react-codemirror/blob/22cc81971a/src/useCodeMirror.ts#L144
// https://gist.github.com/s-cork/e7104bace090702f6acbc3004228f2cb
const createEditorCompartment = () => {
  const compartment = new Compartment();
  const run = (extension: Extension, view: EditorView) => {
    if (compartment.get(view.state)) {
      //动态地重新配置插件
      view.dispatch({ effects: compartment.reconfigure(extension) }); // reconfigure
    } else {
      //向编辑器注入某一个插件
      view.dispatch({
        effects: StateEffect.appendConfig.of(compartment.of(extension))
      }); // inject
    }
  };
  return { compartment, run };
};

//动态语言包函数
let { compartment, run } = createEditorCompartment();
let editor = null;
watch(
  () => props.value,
  n => {
    nextTick(() => {
      let element = document.getElementById("editor" + props.index);
      let state = EditorState.create({
        doc: n, //这是文本
        extensions: [basicSetup, oneDark, java()] //传入的插件数组
      });
      let view = new EditorView({
        state: state, //编辑器状态，编辑器视图创建时初始化的状态
        parent: element //挂载的dom，可以通过parent挂载到指定的div块
      });
      editor = view;
    });
  }
);
//挂载
onMounted(() => {
  let element = document.getElementById("editor" + props.index);
  let state = EditorState.create({
    doc: props.value, //这是文本
    extensions: [basicSetup, oneDark, java()] //传入的插件数组
  });
  let view = new EditorView({
    state: state, //编辑器状态，编辑器视图创建时初始化的状态
    parent: element //挂载的dom，可以通过parent挂载到指定的div块
  });
  editor = view;
});
</script>
